package wassalt.client;

import wassalt.Services.*;
import wassalt.Utils.AppConstants;
import wassalt.Utils.User;
import wassalt.Utils.Util;
import static wassalt.Utils.AppConstants.HTTP_STATUS;
import static wassalt.Utils.AppConstants.URL;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import org.apache.http.HttpStatus;

import android.accounts.Account;
import android.accounts.AccountManager;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;

public class RegistrationActivity extends Activity {

	
	private static final String TAG = "RegistrationActivity";

	private Context mContext = this;
	ProgressDialog dialog;
	AlertDialog alert;
	String fName;
	String lName;
	String mail;
	String mobile;
	boolean connecting = false;
	
	/**
	 * Registration web service path
	 */
	final String REGISTRATION_PATH = "/ManageUsers/registerNewUser";

	private BroadcastReceiver receiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context arg0, Intent resInetent) {
			try {
				Log.d(TAG, "Resposnse from Reg service arrived");
				// updating UI according to response
				int http_status = resInetent.getExtras().getInt(HTTP_STATUS);
				
				if (http_status == HttpStatus.SC_OK) {
					((RegistrationActivity) mContext).registrationSuccess();
					return;
				} else
					throw new Exception();
			} catch (Exception e) {
				((RegistrationActivity) mContext).registrationFail();
			}

		}
	};

	@Override
	protected void onResume() {
		super.onResume();
		initMailSpinner();
		
		IntentFilter filter = new IntentFilter();
		filter.addAction(AppConstants.REGISTRATION_UI_UPDATE_FILTER);
		registerReceiver(receiver, filter);
		
		if (!Util.isConnecting(mContext,AppConstants.REG_CON_KEY))
		{// if the reason is failure call failure scenario 
			String extra=Util.getExtra(mContext, AppConstants.REG_CON_KEY);
			if (extra != null && extra.equals("false"))
				registrationFail();

			else if ((extra != null && extra.equals("true"))||User.isRegistered(mContext))
				{registrationSuccess();
				}				
		}
		
	}
	

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.registration_form);
		
		Log.e(TAG, "Start Registration Activity");

	}

	/**
	 * This method handles the register button fired action first reads data and
	 * validate it if all data is valid it calls register method
	 * 
	 * @param button
	 * @author Gad
	 * @see register
	 */
	public void registerButtonHandler(View button) {

		final EditText fNameField = (EditText) findViewById(R.id.EditTextFName);
		fName = fNameField.getText().toString().trim();

		final EditText lNameField = (EditText) findViewById(R.id.EditTextLName);
		lName = lNameField.getText().toString().trim();

		final EditText mobileField = (EditText) findViewById(R.id.EditTextMobile);
		mobile = mobileField.getText().toString().trim();

		Pattern namePattern = Pattern.compile(AppConstants.NAME_PATTERN);
		Pattern phonePattern = Pattern.compile(AppConstants.PHONE_PATTERN);

		if (!phonePattern.matcher(mobile).matches()) {
			Toast.makeText(this, getString(R.string.inv_phone),
					Toast.LENGTH_SHORT).show();
			return;
		}

		if (!namePattern.matcher(fName).matches()) {
			Toast.makeText(this, getString(R.string.inv_f_name),
					Toast.LENGTH_SHORT).show();
			return;
		}

		if (!namePattern.matcher(lName).matches()) {
			Toast.makeText(this, getString(R.string.inv_l_name),
					Toast.LENGTH_SHORT).show();
			return;
		}

		register();
	}

	/**
	 * Sends service intent to http service to send registration request to the
	 * server
	 * 
	 * @author Gad
	 * 
	 */
	public void register() {
		// Start loading dialog and connecting variables
		setConnectionState(true);
		Util.setConnecting(mContext, AppConstants.REG_CON_KEY);
		Log.d("register isConnecting var",Util.isConnecting(mContext, AppConstants.REG_CON_KEY)+"");
		dialog = ProgressDialog.show(RegistrationActivity.this, "",
				getString(R.string.reg_load_msg), true, false);

		// start back-ground service to handle registration process
		Intent backgroud_regService = new Intent(
				RegistrationService.class.getName());
		backgroud_regService.putExtra(URL, getString(R.string.server_url)
				+ REGISTRATION_PATH);
		backgroud_regService.putExtra(AppConstants.FIRST_NAME, fName);
		backgroud_regService.putExtra(AppConstants.LAST_NAME, lName);
		backgroud_regService.putExtra(AppConstants.MAIL, mail);
		backgroud_regService.putExtra(AppConstants.PHONE, mobile);
		startService(backgroud_regService);

	}

	/**
	 * changes the state of the web service whether it connects to the server or
	 * not according to newState sent it also closes the loading dialog
	 * 
	 * @param newstate
	 *            true means still connecting and false close connection
	 * 
	 */
	private synchronized void setConnectionState(boolean newstate) {
		connecting = newstate;
		Log.e("**conn",connecting+"");
		try {
			if (!connecting && dialog != null)
				dialog.dismiss();

		} catch (Exception e3) {
			Log.e(TAG,"Exception Closing dialog");
		}
	}

	/**
	 * Handles registration success scenario by set connection to false and make
	 * a toast welcome and redirect to main activity
	 * 
	 * @param registeredUser
	 * @author Gad
	 */
	private void registrationSuccess() {
		setConnectionState(false);
		try{
		Toast.makeText(RegistrationActivity.this, getString(R.string.welcome),
				Toast.LENGTH_LONG).show();
		}
		catch (Exception e) {
			Log.e(TAG, "exception showing toast "+e.getMessage());
		}
		Intent intent = new Intent(this, NotificationsListActivity.class);
		startActivityForResult(intent, 0);
		finish();
		
	}

	/**
	 * Handles registration failure by displaying a Message and asks for retry
	 * 
	 * @author Gad
	 */
	private void registrationFail() {
		
		runOnUiThread(new Runnable() {
			
			
			public void run() {
				if(dialog!=null){
					dialog.cancel();
					dialog=null;
				}
				if(alert!=null){
					alert.cancel();
					alert=null;
				}
	
				AlertDialog.Builder builder = new AlertDialog.Builder(
						RegistrationActivity.this);
				builder.setMessage(getString(R.string.reg_fail))
						.setCancelable(false)
						.setPositiveButton(getString(R.string.retry),
								new DialogInterface.OnClickListener() {
									public void onClick(
											DialogInterface dialog1, int id) {
										dialog1.dismiss();
										//dialog1.cancel();
										register();
									}
								})
						.setNegativeButton(getString(R.string.skip),
								new DialogInterface.OnClickListener() {
									public void onClick(
											DialogInterface dialog1, int id) {
										setConnectionState(false);
										// dialog1.dismiss();
										dialog1.cancel();

									}
								});

				alert = builder.create();
				alert.show();

			}
		});
	}

	/**
	 * Returns a list of registered Google account names. If no Google accounts
	 * are registered on the device, a zero-length list is returned.
	 * 
	 * @author Gad
	 */
	private List<String> getGoogleAccounts() {
		Log.e(TAG, "trying to get accounts");
		ArrayList<String> result = new ArrayList<String>();
		Account[] accounts = AccountManager.get(mContext).getAccounts();
		for (Account account : accounts) {
			if (account.type.equals("com.google")) {
				result.add(account.name);
			}
		}

		return result;
	}

	/**
	 * Initialize mails spinner and fills it with google mails
	 * 
	 * @author Gad
	 */
	private void initMailSpinner() {
		List<String> accounts = getGoogleAccounts();

		if (accounts.size() == 0) {
			// if there is no google accounts
			noGoogleAccountWarning();
		} else {

			final Spinner mailSpinner = (Spinner) findViewById(R.id.spinnerEmail);
			ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(
					this, android.R.layout.simple_spinner_dropdown_item, accounts);
			mailSpinner.setAdapter(spinnerAdapter);
			mailSpinner.setSelection(0);
			mailSpinner
					.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
						@Override
						public void onItemSelected(AdapterView<?> arg0,
								View arg1, int pos, long arg3) {
							// change the choosen mail
							mail = (String) mailSpinner.getItemAtPosition(pos)
									.toString();

						}

						@Override
						public void onNothingSelected(AdapterView<?> arg0) {

						}

					});

		}
	}

	/**
	 * Display warning to the user if there is no google accounts and asks him
	 * to add one.
	 * 
	 * @author Gad
	 */
	private void noGoogleAccountWarning() {
		// Show a dialog and invoke the "Add Account" activity if requested
		AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
		builder.setMessage(R.string.needs_account);
		builder.setPositiveButton(R.string.add_account,
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog1, int which) {
						// direct to add accounts system activity
						dialog1.dismiss();
						startActivity(new Intent(Settings.ACTION_ADD_ACCOUNT));
					}
				});
		builder.setNegativeButton(R.string.skip,
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog1, int which) {
						dialog1.dismiss();
						finish();
					}
				});
		builder.setIcon(android.R.drawable.stat_sys_warning);
		builder.setTitle(R.string.attention);
		builder.show();
	}

	@Override
	protected void onPause() {
		Log.e("onPause","OnPause");
		// unregister the receiver and set dialog to null
		//Log.d("register isConnecting var",Util.getRemoveExtra(mContext, AppConstants.REG_CON_KEY)+"");
		//if(!connecting)
		unregisterReceiver(receiver);
		if (!Util.isConnecting(mContext, AppConstants.REG_CON_KEY))
			{
			Util.clearConnection(mContext, AppConstants.REG_CON_KEY);
			}

		if(dialog!=null){
			dialog.cancel();
			dialog = null;}
		super.onPause();
	}
	@Override
	public void onBackPressed() {
		setConnectionState(false);
		super.onBackPressed();
	}

}
